package com.jingdianjichi.subject.domain.service.impl;


import com.alibaba.fastjson.JSON;
import com.jingdianjichi.subject.common.entity.PageResult;
import com.jingdianjichi.subject.common.enums.IsDeletedFlageEnum;
import com.jingdianjichi.subject.common.enums.SubjectLikedStatusEnum;
import com.jingdianjichi.subject.common.util.LoginUtil;
import com.jingdianjichi.subject.domain.convert.SubjectLikedBOConverter;
import com.jingdianjichi.subject.domain.entity.SubjectLikedBO;
import com.jingdianjichi.subject.domain.redis.RedisUtil;
import com.jingdianjichi.subject.domain.service.SubjectLikedDomainService;
import com.jingdianjichi.subject.infra.basic.entity.SubjectInfo;
import com.jingdianjichi.subject.infra.basic.entity.SubjectLiked;
import com.jingdianjichi.subject.infra.basic.service.SubjectInfoService;
import com.jingdianjichi.subject.infra.basic.service.SubjectLikedService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 题目点赞表 领域service实现了
 *
 * @author dal
 * @since 2024-06-07 16:05:11
 */
@Service
@Slf4j
public class SubjectLikedDomainServiceImpl implements SubjectLikedDomainService {

    @Resource
    private SubjectLikedService subjectLikedService;
    @Resource
    private SubjectInfoService subjectInfoService;
    //题目点赞的所有人
    private static final String SUBJECT_LIKED_KEY = "subject.liked";
    //题目点赞数量
    private static final String SUBJECT_LIKED_COUNT_KEY = "subject.liked.count";
    //题目是否被我点赞
    private static final String SUBJECT_LIKED_DETAIL_KEY = "subject.liked.detail";
 @Resource
 private RedisUtil redisUtil;
    @Override
    public void add(SubjectLikedBO subjectLikedBO) {
        Long subjectId = subjectLikedBO.getSubjectId();
        String likeUserId = subjectLikedBO.getLikeUserId();
        Integer status = subjectLikedBO.getStatus();
        String hashKet = subjectId+":" +likeUserId;
       redisUtil.putHash(SUBJECT_LIKED_KEY,hashKet,status);
       String countKey = SUBJECT_LIKED_COUNT_KEY+"."+subjectId;
       String detailKey = SUBJECT_LIKED_DETAIL_KEY+"."+subjectId+"."+likeUserId;
       if (SubjectLikedStatusEnum.LIKED.getCode()==status){
           //如果是点赞，则点赞数+1
           redisUtil.increment(countKey,1);
           redisUtil.set(detailKey,"1");
       }else {
           //取消点赞，点赞数-1，如果不存在或点赞数小于等于0，则不处理
           Integer count = redisUtil.getInt(countKey);
           if (Objects.isNull(count) || count<=0){
               return;
           }
           redisUtil.increment(countKey,-1);
           //取消点赞，删除点赞详情
           redisUtil.del(detailKey);
       }
    }



    private String buildSubjectLikedKey(String subjectId, String userId) {
        return  subjectId+":"+userId;
    }
    @Override
    public Boolean update(SubjectLikedBO subjectLikedBO) {
        SubjectLiked subjectLiked = SubjectLikedBOConverter.INSTANCE.convertBOToEntity(subjectLikedBO);
        return subjectLikedService.update(subjectLiked) > 0;
    }

    @Override
    public Boolean delete(SubjectLikedBO subjectLikedBO) {
        SubjectLiked subjectLiked = new SubjectLiked();
        subjectLiked.setId(subjectLikedBO.getId());
        subjectLiked.setIsDeleted(IsDeletedFlageEnum.DELETE.getCode());
        return subjectLikedService.update(subjectLiked) > 0;
    }

    @Override
    public void syncLiked() {
      Map<Object,Object> subjectLikedMap = redisUtil.getHashAndDelete(SUBJECT_LIKED_KEY);
      if (log.isInfoEnabled()){
          log.info("syncLiked.subjectLikedMap:{}", JSON.toJSONString(subjectLikedMap));
      }
      if (MapUtils.isEmpty(subjectLikedMap)){
          return;
      }
      //批量同步到数据库
        List<SubjectLiked> subjectLikedList = new LinkedList<>();
      subjectLikedMap.forEach((key,val)->{
          SubjectLiked subjectLiked = new SubjectLiked();
          //分割成多个子字符串，并将其存储在名为 keyArr 的字符串数组中。
          String[] keyArr = key.toString().split(":");
          String subjectId = keyArr[0];
          String likedUser = keyArr[1];
          String status = val.toString();
          subjectLiked.setSubjectId(Long.valueOf(subjectId));
          subjectLiked.setLikeUserId(likedUser);
          subjectLiked.setStatus(Integer.valueOf(status));
          subjectLiked.setIsDeleted(IsDeletedFlageEnum.UN_DELETE.getCode());
          subjectLikedList.add(subjectLiked);
      });
        subjectLikedService.batchInsert(subjectLikedList);
    }

    @Override
    public PageResult<SubjectLikedBO> getSubjectLikedPage(SubjectLikedBO subjectLikedBO) {
        PageResult<SubjectLikedBO> pageResult = new PageResult<>();
        pageResult.setPageNo(subjectLikedBO.getPageNo());
        pageResult.setPageSize(subjectLikedBO.getPageSize());
        int start = (subjectLikedBO.getPageNo() - 1) * subjectLikedBO.getPageSize();
        SubjectLiked subjectLiked = SubjectLikedBOConverter.INSTANCE.convertBOToEntity(subjectLikedBO);
        subjectLiked.setLikeUserId(LoginUtil.getLoginId());
        //查询我点赞的题目数
        int count = subjectLikedService.countByCondition(subjectLiked);
        if (count == 0) {
            return pageResult;
        }
        //获取题目id
        List<SubjectLiked> subjectLikedList = subjectLikedService.queryPage(subjectLiked, start,
                subjectLikedBO.getPageSize());
        List<SubjectLikedBO> subjectInfoBOS = SubjectLikedBOConverter.INSTANCE.convertListInfoToBO(subjectLikedList);
        subjectInfoBOS.forEach(info -> {
            //获取题目详情
            SubjectInfo subjectInfo = subjectInfoService.queryById(info.getSubjectId());
            //添加题目名称
            info.setSubjectName(subjectInfo.getSubjectName());
        });
        pageResult.setRecords(subjectInfoBOS);
        pageResult.setTotal(count);
        return pageResult;
    }


    @Override
    public Boolean isLiked(String subjectId, String userId) {

        String detailKey = SUBJECT_LIKED_DETAIL_KEY+"."+subjectId+"."+userId;
        return redisUtil.exist(detailKey);
    }

    @Override
    public Integer getLikedCount(String subjectId) {
        String countKey = SUBJECT_LIKED_COUNT_KEY+"."+subjectId;
        Integer count = redisUtil.getInt(countKey);
        if (Objects.isNull(count) || count<=0){
            return 0;
        }
        return redisUtil.getInt(countKey);
    }
}
